package org.rcy.ruicingmarket.user;

import org.apache.commons.lang3.StringUtils;
import org.rcy.framework.cache.redis.CommonCache;
import org.rcy.framework.utils.validate.ValidateCodeUtils;
import org.rcy.ruicingmarket.cache.UmsCacheGroup;
import org.rcy.ruicingmarket.client.MessageClient;
import org.rcy.ruicingmarket.common.result.PageResult;
import org.rcy.ruicingmarket.common.result.StatusCode;
import org.rcy.ruicingmarket.common.utils.CollectionBeanUtils;
import org.rcy.ruicingmarket.common.utils.TokenUtils;
import org.rcy.ruicingmarket.exception.UmsException;
import org.rcy.ruicingmarket.template.TencentSMSTemplate;
import org.rcy.ruicingmarket.vo.SMSParam;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.springframework.transaction.annotation.Transactional;


/**
 * @author RuicyWu
 * @Date 2021-12-22 14:34:38
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class UserService {

	@Autowired
	private UserDao userDao;
	@Autowired
	private BCryptPasswordEncoder encoder;
	@Autowired
	private CommonCache commonCache;
	@Autowired
	private MessageClient messageClient;

	@Value("${ums.token.encryptkey:rcy}")
	private String encryptkey;


	/**
	 * 根据id查询User
	 *
	 * @param id
	 * @return User
	 */
	public UserVo findById(Long id) {
		User user = userDao.get(id);
		if (user != null) {
			UserVo userVo = new UserVo();
			userVo.setStatus(user.getStatus());
			return userVo;
		}
		return null;
	}

	/**
	 * 更新密码
	 *
	 * @param vo
	 */
	public void updatePassword(PasswordChangeVo vo) {
		User user = userDao.get(vo.getUid());
		if (encoder.matches(vo.getOldPassword(), user.getPassword())) {
			String encodenewpass = encoder.encode(vo.getNewPassword());
			user.setPassword(encodenewpass);
			user.setCreateTime(null);
			userDao.update(user, true);
		}
	}

	/**
	 * 根据id删除User
	 *
	 * @param id
	 */
	public void remove(Long id) {
		userDao.delete(id);
	}


	/**
	 * 发送验证码
	 * @param target 接收者
     * @param mode 发送方式 手机或邮箱
	 */
	public void sendLoginOrRegisterCode(String target, LoginOrRegisterMode mode , String cacheGroup) {
		int code = ValidateCodeUtils.generateValidateCode(4);
		System.out.println(target + "收到验证码是：" + code);
		//2.将验证码放入redis
        commonCache.cache(cacheGroup,target,code+"",60*5);
		//五分钟过期
		if (mode.equals(LoginOrRegisterMode.MOBILE)) {
			SMSParam<TencentSMSTemplate> smsParam = new SMSParam<>();
			smsParam.setTarget(target);
			smsParam.setContent(code+"");
			smsParam.setT(new TencentSMSTemplate());
			messageClient.sendSMS(smsParam);
		} else {

		}
	}


	/**
	 * 用户注册
	 *
	 * @param vo
	 */
	public String registUser(RegisterVo vo) {
		String code = (String) commonCache.getData("REGISTERCODE", vo.getMode().equals(LoginOrRegisterMode.MOBILE) ? vo.getMobile() : vo.getEmail());
		if (StringUtils.isBlank(code) || !vo.getCode().equals(code)) {
			throw new UmsException(StatusCode.VALIDATECODEERROR.getReasonPhrase(), StatusCode.VALIDATECODEERROR);
		}
		String encode = encoder.encode(vo.getPassword());
		User user = new User();
		BeanUtils.copyProperties(vo, user);
		user.setPassword(encode);
		user = userDao.save(user);
		if(user.getId() != null) {
			String loginToken = TokenUtils.getToken(user.getId(), encryptkey);
			commonCache.cache(UmsCacheGroup.REGISTERCODE, loginToken, vo.getMode().equals(LoginOrRegisterMode.MOBILE) ? vo.getMobile() : vo.getEmail(), 3600);
			return loginToken;
		}
		throw new UmsException(StatusCode.REGISTERFAILED.getReasonPhrase(), StatusCode.REGISTERFAILED);
	}


	/**
	 * 修改User
	 *
	 * @param vo
	 */
	public void edit(UserEditVo vo) {
		User user = new User();
		BeanUtils.copyProperties(vo, user);
		user.setCreateTime(null);
		user.setId(vo.getUid());
		userDao.update(user, true);
	}

	/**
	 * 查询所有User
	 *
	 * @return List<UserShowVo>
	 */
	public List<UserVo> findAll() {
		return CollectionBeanUtils.copyListProperties(userDao.select(new User()), UserVo::new,
				(user, vo) -> {
            vo.setStatus(user.getStatus());
        });
	}

	/**
	 * 登录验证
	 *
	 * @param vo
	 * @return
	 */
	public String loginVerify(LoginVo vo) {
		LoginOrRegisterMode mode = vo.getMode();
		if (mode.equals(LoginOrRegisterMode.MOBILE)) {
			User user = userDao.findByMobile(vo.getMobile());
			if (user != null && encoder.matches(vo.getPassword(), user.getPassword())) {
				String loginToken = TokenUtils.getToken(user.getId(), encryptkey);
				commonCache.cache(UmsCacheGroup.LOGINTOKEN, loginToken, user.getMobile(), 3600);
				return loginToken;
			}
		} else {
			User user = userDao.findByEmail(vo.getEmail());
			if (user != null && encoder.matches(vo.getPassword(), user.getPassword())) {
				String loginToken = TokenUtils.getToken(user.getId(), encryptkey);
				commonCache.cache(UmsCacheGroup.LOGINTOKEN, loginToken, user.getEmail(), 3600);
				return loginToken;
			}
		}
		throw new UmsException(StatusCode.USERANDPASSWORDERROR.getReasonPhrase(), StatusCode.USERANDPASSWORDERROR);
	}

	/**
	 * 条件分页查询user
	 *
	 * @param queryCondition
	 * @return
	 */
	public PageResult<UserVo> queryUserByCondition(UserQueryCondition queryCondition) {
		int count = userDao.queryPageCount(queryCondition);
		List<User> users = userDao.queryPage(queryCondition);
		return new PageResult<UserVo>
				(queryCondition.getPageNo(),
						queryCondition.getPageSize(),
						count, CollectionBeanUtils.copyListProperties(users, UserVo::new,
						(user, vo) -> {
							vo.setStatus(user.getStatus());
                            vo.setUid(user.getId());
                        }));

	}


	/**
	 * 冻结账号
	 *
	 * @param id
	 */
	public void freezeUser(Long id) {
		userDao.freezeUser(id);
	}

}
